<?php
/**
 * Created by PhpStorm.
 * User: 12297
 * Date: 2018/5/17
 * Time: 1:07
 */
namespace app\api\service;

use app\common\BaseHelper;
use app\common\DictConstant;
use app\common\model\Groupdetail;
use app\common\model\Groupproduct;
use app\common\model\Orderproductdetail;
use app\common\model\Product;
use app\common\model\Productspecgroups;
use app\lib\exception\ParameterException;
use think\Db;
use think\Exception;

/**
 * 团购
 * Class Group
 * @package app\api\service
 */
class Group{
    //订单商品列表，也就是客户端传过来的products
    protected $oProducts;

    //真实的商品信息，从数据库查出来的（包括库存量）
    protected $products;

    private $groupID;
    private $groupType;
    private $userid;
    private $orderId;
    private $tenantId;
    private $orderType;
    private $storeId;
    private $unigroupId = NULL;
    protected $deliverAddress = NULL;
    protected $userName = NULL;
    protected $userPhone = NULL;
    private $content = NULL;
    private $groupdetailId = NULL;
    private $subscribeDate = NULL;
    private $formId = NULL;
    protected $freight = 0;
    protected $packingfee = 0;


    public function makegroup($userid,$orderdata,$oProducts){
        $this->oProducts = $oProducts;
        $this->products = $this->getProductsByOrder($oProducts);
        $this->groupID = $orderdata['id'];
        $this->groupType = $orderdata['grouptype'];
        $this->userid = $userid;
        $this->orderId = $orderdata['orderId'];
        $this->tenantId = Token::getTenantid();
        $this->orderType = $orderdata['orderType'];
        $this->content = isset($orderdata['content'])?$orderdata['content']:NULL;
        $this->unigroupId = isset($orderdata['unigroupId'])?$orderdata['unigroupId']:NULL;
        $this->formId = isset($orderdata['formId'])?$orderdata['formId']:NULL;
        $this->freight = isset($orderdata['freight'])?$orderdata['freight']:0;
        $this->packingfee = isset($orderdata['packingfee'])?$orderdata['packingfee']:0;
        $groupproduct = Groupproduct::get($this->groupID);
        if(!$groupproduct){
            throw new ParameterException([
                'msg' => '此团购商品不存在'
            ]);
        }
        $groupdetail = new Groupdetail();
        $grouping = $groupdetail->where(['groupId'=>$this->groupID,'userId'=>$userid,'status'=>1,'isActive'=>1])->find();
        if($grouping){
            throw new ParameterException([
                'msg' => '此商品您正在参加团购，不能重复参加'
            ]);

        }
        $this->storeId = $groupproduct->storeId;
        $id = BaseHelper::getUUID();
        $this->groupdetailId = $id;
        $groupdetail->id = $id;
        $groupdetail->groupId = $this->groupID;
        $groupdetail->userId = $this->userid;
        $groupdetail->storeId = $this->storeId;
        if($this->groupType==0){
            //参团(会传递unigroupId)
            $cproup = $groupdetail->where(['id'=>$this->unigroupId,'status'=>1,'isActive'=>1])->find();
            if(!$cproup){
                throw new ParameterException([
                    'msg' => '此团不存在或者已经结束'
                ]);
//                return show(config('status.ERROR_STATUS'),'error','此团不存在或者已经结束！');
            }

            $groupdetail->originator = $cproup->originator;
            $groupdetail->unigroupId = $cproup->id;
            $groupdetail->save();

        }else{
            //开团（团长）
            //userid = originator 生成unigroupId（唯一标识此团）
            $groupdetail->unigroupId = $id;
            $groupdetail->originator = $this->userid;
            $groupdetail->save();
        }
        $this->unigroupId = $groupdetail->unigroupId;

        //创建订单
        return $this->groupplace($orderdata);


    }


    private function groupplace($orderdata){
        if($this->orderType == DictConstant::ORDER_TYPE_ONLINE){
            if($this->ischeckaddress($orderdata)){
                $this->deliverAddress = $orderdata['deliverAddress'];
                $this->userName = $orderdata['userName'];
                $this->userPhone = $orderdata['userPhone'];
            }else{
                throw new ParameterException([
                    'msg' => '用户收货信息异常！',
                ]);
            }

        }else{
            if(isset($orderdata['subscribeDate']) && !empty($orderdata['subscribeDate'])){
                $this->subscribeDate = $orderdata['subscribeDate'];
            }else{
                throw new ParameterException([
                    'msg' => '预约时间异常！'
                ]);
            }
        }
        $status = $this->getOrderStatus();
        if(!$status['pass']){
            $status['order_id'] = -1;
            return $status;
        }
        //运费
        if($this->freight){
            $status['orderPrice'] += $this->freight;
        }
        //包装费
        if($this->packingfee){
            $status['orderPrice'] += $this->packingfee;
        }
        //开始创建订单
        $orderSnap = $this->snapOrder($status);
        $order = $this->createOrder($orderSnap);
        $order['pass'] = true;
        return $order;
    }

    private function createOrder($orderSnap){
        Db::startTrans();
        try{
            $order = \app\common\model\Order::get($this->orderId);
            if($order){
                $order->content = $this->content;
                $order->deliverAddress = $this->deliverAddress;
                $order->userName = $this->userName;
                $order->userPhone = $this->userPhone;
                $order->subscribeDate = $this->subscribeDate;
                $order->freight = $this->freight;
                $order->save();
                Db::commit();
                return [
                    'orderNO' => $order->orderNO,
                    'orderId' => $order->id,
                    'create_time' => $order->create_time
                ];
            }
            $orderNo = Order::makeOrderNo();
            $order = new \app\common\model\Order();
            $order->id = $this->orderId;
            $order->createUser = $this->userid;
            $order->tenantId = $this->tenantId;
            $order->storeId = $this->storeId;
            $order->spellGroupId = $this->groupID;
            $order->userSpellGroupId = $this->unigroupId;
            $order->content = $this->content;
            $order->deliverAddress = $this->deliverAddress;
            $order->userName = $this->userName;
            $order->userPhone = $this->userPhone;
            $order->subscribeDate = $this->subscribeDate;
            $order->type = $this->orderType;
            $order->orderNO = $orderNo;
            $order->total = $orderSnap['orderPrice'];
            $order->freight = $this->freight;
            $order->packingfee = $this->packingfee;
            $order->total_count = $orderSnap['totalCount'];
            $order->linkType = 1; //拼团订单
            $order->formId = $this->formId;
            $order->save();
            $orderId = $order->id;
            $create_time = $order->create_time;
            $i = 0;
            foreach ($this->oProducts as &$p)
            {
                $p['id'] = BaseHelper::getUUID();
                $p['orderId'] = $orderId;
                $p['productName'] = $orderSnap['pStatus'][$i]['title'];
                $p['productImg'] =  $orderSnap['pStatus'][$i]['imgUrl'];
                $p['specid'] =  isset($orderSnap['pStatus'][$i]['specid'])?$orderSnap['pStatus'][$i]['specid']:null;
                $p['productSpec'] =  isset($orderSnap['pStatus'][$i]['specDetails1'])?$orderSnap['pStatus'][$i]['specDetails1']:null;
                $p['productSpec1'] =  isset($orderSnap['pStatus'][$i]['specDetails2'])?$orderSnap['pStatus'][$i]['specDetails2']:null;
                $p['productSpec2'] =  isset($orderSnap['pStatus'][$i]['specDetails3'])?$orderSnap['pStatus'][$i]['specDetails3']:null;
                $p['price'] = $orderSnap['pStatus'][$i]['currentPrice'];
                $p['gprice'] = $orderSnap['gprice'];
                $p['userId'] = $this->userid;
                $p['tenantId'] = $this->tenantId;
                $i++;
            }
            $orderProduct = new Orderproductdetail();
            $orderProduct->saveAll($this->oProducts,false);
            //往用户拼团详情表里插入orderid
            Groupdetail::where('id',$this->groupdetailId)->update(['orderId'=>$orderId]);
            Db::commit();
            return [
                'orderNO' => $orderNo,
                'orderId' => $orderId,
                'create_time' => $create_time
            ];
        }catch (Exception $ex){
            Db::rollback();
            throw $ex;
        }
    }

    // 生成订单快照(历史订单信息，不随着商品的变化而变化)
    private function snapOrder($status){
        $snap = [
            'orderPrice' => 0,
            'totalCount' => 0,
            'gprice' => 0,
            'pStatus' => [],
            'snapName' => '',
            'snapImg' => ''
        ];
        $snap['orderPrice'] = $status['orderPrice'];
        $snap['totalCount'] = $status['totalCount'];
        $snap['pStatus'] = $status['pStatusArray'];
        $snap['gprice'] = $status['gprice'];
        $snap['snapName'] = $this->products[0]['title'];
        $snap['snapImg'] = $this->products[0]['imgUrl'];
        if (count($this->products) > 1)
        {
            $snap['snapName'] .= '等';
        }
        return $snap;
    }

    /**
     * 根据订单ID进行库存量检测
     * @param $orderID
     * @return array
     */
    public function checkOrderStock($orderID){
        $oProducts = Orderproductdetail::where('orderId','=',$orderID)->select();
        $this->oProducts = $oProducts;
        $this->products = $this->getProductsByOrder($oProducts);
        $status = $this->getOrderStatus();
        return $status;
    }

    private function getOrderStatus(){
        $status = [
            'pass' => true,
            'orderPrice' => 0,
            'totalCount' => 0,
            'pStatusArray' => [],
            'gprice' => 0,
        ];
        foreach ($this->oProducts as $oProduct){
            $pStatus = $this->getProductStatus($oProduct['productId'],$oProduct['count'],$this->products);
            if(!$pStatus['havestoreCount']){
                $status['pass'] = false;
            }
            $status['orderPrice'] += $pStatus['totalPrice'];
            $status['totalCount'] += $pStatus['counts'];
            $status['gprice'] = $pStatus['groupPrice'];
            $status['title'] = $pStatus['title'];
            array_push($status['pStatusArray'], $pStatus);
        }
        return $status;
    }

    private function getProductStatus($oPID,$oCount,$products){
        $pStatus = [
            'id' => null,
            'havestoreCount' => false,
            'counts' => 0,
            'currentPrice' => 0,
            'groupPrice' => 0,
            'title' => '',
            'totalPrice' => 0,
            'imgUrl' => null,
            'specDetails1' => null,
            'specDetails2' => null,
            'specDetails3' => null
        ];
        for ($i = 0; $i < count($products); $i++)
        {
            if ($oPID == $products[$i]['id'])
            {
                $pIndex = $i;
            }
        }
        if($pIndex == -1){
            // 客户端传递的productId有可能根本不存在
            throw new OrderException([
                'msg' => 'id为' . $oPID . '的商品不存在，创建订单失败'
            ]);
        }else{
            $product = $products[$pIndex];
            $pStatus['id'] = $product['id'];
            $pStatus['title'] = $product['title'];
            $pStatus['counts'] = $oCount;
            $pStatus['currentPrice'] = $product['currentPrice'];
            $pStatus['groupPrice'] = $product['groupPrice'];
            $pStatus['imgUrl'] = $product['imgUrl'];
            $pStatus['totalPrice'] = $product['groupPrice'] * $oCount;
            if(isset($product['specDetails1']) && !empty($product['specDetails1'])){
                $pStatus['specDetails1'] = $product['specDetails1'];
            }
            if(isset($product['specDetails2']) && !empty($product['specDetails2'])){
                $pStatus['specDetails2'] = $product['specDetails2'];
            }
            if(isset($product['specDetails3']) && !empty($product['specDetails3'])){
                $pStatus['specDetails3'] = $product['specDetails3'];
            }
            if(isset($product['specid']) && !empty($product['specid'])){
                $pStatus['specid'] = $product['specid'];
            }

            if($product['isStore'] == 0){
                $pStatus['havestoreCount'] = true;
            }else{
                if($product['storeCount'] - $oCount >= 0){
                    $pStatus['havestoreCount'] = true;
                }
            }

        }
        return $pStatus;
    }

    private function ischeckaddress($orderdata){
        if(isset($orderdata['deliverAddress']) && !empty($orderdata['deliverAddress']) && isset($orderdata['userName']) && !empty($orderdata['userName']) && isset($orderdata['userPhone']) && !empty($orderdata['userPhone'])){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 根据订单查找真实的商品信息
     * @param $oProducts
     * @return mixed
     * @throws ParameterException
     */
    private function getProductsByOrder($oProducts){
        $oPIDs = [];
        $specIDS = [];
        if(!is_array($oProducts)){
            throw new ParameterException([
                'msg' => '缺少购买的商品信息'
            ]);
        }
        foreach ($oProducts as $item){
            if(isset($item['specid'])){
                array_push($specIDS,$item['specid']);
            }
            array_push($oPIDs,$item['productId']);
        }
        $products = Product::all()->visible(['id','currentPrice','groupPrice','storeCount','isStore','title','imgUrl','specClass'])->toArray();
        if(count($specIDS)>0){
            $specs = Productspecgroups::all($specIDS)->visible(['id','specDetails1','specDetails2','specDetails3','currentPrice','groupPrice','storeCount','isStore','productId'])->toArray();
            foreach ($products as &$product){
                if($product['specClass']==2){
                    foreach ($specs as $spec){
                        if($spec['productId']==$product['id']){
                            $product['currentPrice'] = $spec['currentPrice'];
                            $product['groupPrice'] = $spec['groupPrice'];
                            $product['specDetails1'] = $spec['specDetails1'];
                            $product['specDetails2'] = $spec['specDetails2'];
                            $product['specDetails3'] = $spec['specDetails3'];
                            $product['storeCount'] = $spec['storeCount'];
                            $product['specid'] = $spec['id'];

                        }
                    }
                }
            }
        }
        return $products;
    }
}